﻿using DotNetCommon.Expressions.Base;
using DotNetCommon.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace DotNetCommon.Expressions.Visit
{
    #region 算数 + - / * %
    /// <summary>
    /// 示例: a + b
    /// </summary>
    internal class AddVisit : BinaryVisit
    {
        protected override string MarkString => "+";
    }
    /// <summary>
    /// 示例: a - b 
    /// </summary>
    internal class SubtractVisit : BinaryVisit
    {
        protected override string MarkString => "-";
    }
    /// <summary>
    /// 示例: a * b
    /// </summary>
    internal class MultiplyVisit : BinaryVisit
    {
        protected override string MarkString => "*";
    }
    /// <summary>
    /// 示例: a% b
    /// </summary>
    internal class ModuloVisit : BinaryVisit
    {
        protected override string MarkString => "%";
    }
    /// <summary>
    /// 示例: a/b
    /// </summary>
    internal class DivideVisit : BinaryVisit
    {
        protected override string MarkString => "/";
    }
    /// <summary>
    /// 示例: - intx
    /// </summary>
    internal class NegateVisit : UnaryVisit
    {
        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            return $"-{node.Children[0].FullMarkString}";
        }
    }
    /// <summary>
    /// 示例: +a
    /// </summary>
    internal class UnaryPlusVisit : BaseVisit
    {
        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            return $"+{node.Children[0].FullMarkString}";
        }
    }
    #endregion
    #region 逻辑运算 位运算
    /// <summary>
    /// 示例: a &amp;&amp; b
    /// </summary>
    internal class AndAlsoVisit : BinaryVisit
    {
        protected override string MarkString => "&&";
        /// <summary>
        /// 再次简化,处理短路
        /// </summary>
        /// <param name="node"></param>
        protected override void Reduce2(ExpressionNode node)
        {
            //短路简化
            var canReduce = false;
            for (int i = 0; i < node.Children.Count; i++)
            {
                var child = node.Children[i];
                if (child.NodeType == ExpressionType.Constant)
                {
                    var con = child.Expression as ConstantExpression;
                    if (con.Value.To<bool>() == false)
                    {
                        //短路
                        canReduce = true;
                        break;
                    }
                }
            }
            if (canReduce)
            {
                var contant = Expression.Constant(false);
                node.Expression = contant;
                node._updateRequest = true;
                node.Children.Clear();
                node.IsParameter = false;
            }
        }
    }
    /// <summary>
    /// 示例: a || b
    /// </summary>
    internal class OrElseVisit : BinaryVisit
    {
        protected override string MarkString => "||";
        /// <summary>
        /// 再次简化, 处理短路
        /// </summary>
        /// <param name="node"></param>
        protected override void Reduce2(ExpressionNode node)
        {
            //短路简化
            var canReduce = false;
            for (int i = 0; i < node.Children.Count; i++)
            {
                var child = node.Children[i];
                if (child.NodeType == ExpressionType.Constant)
                {
                    var con = child.Expression as ConstantExpression;
                    if (con.Value.To<bool>())
                    {
                        //短路
                        canReduce = true;
                        break;
                    }
                }
            }
            if (canReduce)
            {
                var contant = Expression.Constant(true);
                node.Expression = contant;
                node._updateRequest = true;
                node.Children.Clear();
                node.IsParameter = false;
            }
        }
    }
    /// <summary>
    /// 示例: !b
    /// </summary>
    internal class NotVisit : UnaryVisit
    {
        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            return $"!{node.Children[0].FullMarkString}";
        }
    }
    /// <summary>
    /// 示例: bool1 &amp; bool2 或 bit1 &amp; bit2
    /// </summary>
    internal class AndVisit : BinaryVisit
    {
        protected override string MarkString => "&";
    }
    /// <summary>
    /// 示例: a | b
    /// </summary>
    internal class OrVisit : BinaryVisit
    {
        protected override string MarkString => "|";
    }
    /// <summary>
    /// 示例: a >> b
    /// </summary>
    internal class RightShiftVisit : BinaryVisit
    {
        protected override string MarkString => ">>";
    }
    /// <summary>
    /// 示例: a &lt;&lt; b
    /// </summary>
    internal class LeftShiftVisit : BinaryVisit
    {
        protected override string MarkString => "<<";
    }
    /// <summary>
    /// 按位或逻辑 XOR 运算，如 C# 中的 (a ^ b) 和 Visual Basic 中的 (a Xor b)。
    /// </summary>
    internal class ExclusiveOrVisit : BinaryVisit
    {
        protected override string MarkString => "^";
    }
    /// <summary>
    /// 二进制反码运算，如 C# 中的 (~a)
    /// </summary>
    internal class OnesComplementVisit : UnaryVisit
    {
        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            return $"~{node.Children[0].FullMarkString}";
        }
    }
    #endregion
    #region 关系运算
    /// <summary>
    /// 示例: a==b
    /// </summary>
    internal class EqualVisit : BinaryVisit
    {
        protected override string MarkString => "==";
    }
    /// <summary>
    /// 示例: a != b
    /// </summary>
    internal class NotEqualVisit : BinaryVisit
    {
        protected override string MarkString => "!=";
    }
    /// <summary>
    /// 示例: a &lt;= b 
    /// </summary>
    internal class LessThanOrEqualVisit : BinaryVisit
    {
        protected override string MarkString => "<=";
    }
    /// <summary>
    /// 示例: a &lt; b
    /// </summary>
    internal class LessThanVisit : BinaryVisit
    {
        protected override string MarkString => "<";
    }
    /// <summary>
    /// 示例: >=
    /// </summary>
    internal class GreaterThanOrEqualVisit : BinaryVisit
    {
        protected override string MarkString => ">=";
    }
    /// <summary>
    /// 示例: >
    /// </summary>
    internal class GreaterThanVisit : BinaryVisit
    {
        protected override string MarkString => ">";
    }
    #endregion
    #region 其他
    /// <summary>
    /// 示例: arr[1]
    /// </summary>
    internal class ArrayIndexVisit : BaseVisit
    {
        protected override void Prepare(ExpressionNode node)
        {
            var binary = node.Expression as BinaryExpression;
            node.Children.Add(new ExpressionNode
            {
                Parent = node,
                Children = new List<ExpressionNode>(),
                Expression = binary.Left
            });
            node.Children.Add(new ExpressionNode
            {
                Parent = node,
                Children = new List<ExpressionNode>(),
                Expression = binary.Right
            });
        }

        protected override Expression Rebuild(ExpressionNode node)
        {
            var binary = node.Expression as BinaryExpression;
            return binary.Update(node.Children[0].Expression, binary.Conversion, node.Children[1].Expression);
        }

        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            return $"{node.Children[0].FullMarkString}[{node.Children[1].FullMarkString}]";
        }
    }
    /// <summary>
    /// 示例: arr.Length
    /// </summary>
    internal class ArrayLengthVisit : UnaryVisit
    {
        protected override void Prepare(ExpressionNode node)
        {
            var arrLengthExpression = node.Expression as UnaryExpression;
            node.Children.Add(new ExpressionNode
            {
                Parent = node,
                Children = new List<ExpressionNode>(),
                Expression = arrLengthExpression.Operand
            });
        }

        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            var arrLengthExpression = node.Expression as UnaryExpression;
            return $"{arrLengthExpression.Type.GetClassFullName()}.Length";
        }
    }
    /// <summary>
    /// 重点处理
    /// </summary>
    internal class CallVisit : BaseVisit
    {
        protected override void Prepare(ExpressionNode node)
        {
            var call = node.Expression as MethodCallExpression;
            var obj = call.Object;
            var method = call.Method;
            var args = call.Arguments;
            node.Children.Add(new ExpressionNode { Expression = call.Object, Parent = node, Children = new List<ExpressionNode>() });
            args.ForEach(i => node.Children.Add(new ExpressionNode { Parent = node, Expression = i, Children = new List<ExpressionNode>() }));
        }

        protected override Expression Rebuild(ExpressionNode node)
        {
            var call = node.Expression as MethodCallExpression;
            return call.Update(node.Children[0].Expression, node.Children.Skip(1).Select(i => i.Expression));
        }

        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            var call = node.Expression as MethodCallExpression;
            return $"{call.Method.DeclaringType.GetClassFullName()}.{call.Method.Name}({node.Children.Skip(1).Select(i => i.FullMarkString).ToStringSeparated(",")})";
        }
    }
    /// <summary>
    /// 示例: i=i??0
    /// </summary>
    internal class CoalesceVisit : BinaryVisit
    {
        protected override string MarkString => "??";

        protected override Expression Rebuild(ExpressionNode node)
        {
            if (node.Children[0].NodeType == ExpressionType.Constant)
            {
                node._updateRequest = true;
                node.IsParameter = false;
                // int? ok=2;
                // ok??2
                //取左边的值[2],但类型保留整体的即[int32],如果直接使用[ok]的值,那么整体的类型将改成[int32?]，这样会导致 binary.Update(...)报错
                var exp = Expression.Constant((node.Children[0].Expression as ConstantExpression).Value, node.Expression.Type);
                node.Children.Clear();
                return exp;
            }
            else
            {
                return base.Rebuild(node);
            }
        }

        //因为 [bool? ok=true; p=>ok??p.Id>1] 整体是bool,但Left是bool?(ok),所以直接是否[ok]后会导致整体变为[book?],所以暂时先放在Rebuild中一起处理
        //??考虑,将所有类型的Reduce2逻辑都转到Rebuild方法下?
        //protected override void Reduce2(ExpressionNode node)
        //{
        //    if (node.NodeType != ExpressionType.Constant && node.Children[0].NodeType == ExpressionType.Constant)
        //    {
        //        node._updateRequest = true;
        //        node.IsParameter = false;
        //        node.Children = null;
        //        node.Expression = node.Children[0].Expression;
        //    }
        //}
    }
    /// <summary>
    /// 示例: i=i>1?1:i
    /// </summary>
    internal class ConditionalVisit : BaseVisit
    {
        protected override void Prepare(ExpressionNode node)
        {
            var condition = node.Expression as ConditionalExpression;
            node.Children.Add(new ExpressionNode
            {
                Children = new List<ExpressionNode>(),
                Expression = condition.Test,
                Parent = node
            });
            node.Children.Add(new ExpressionNode
            {
                Children = new List<ExpressionNode>(),
                Expression = condition.IfTrue,
                Parent = node
            });
            node.Children.Add(new ExpressionNode
            {
                Children = new List<ExpressionNode>(),
                Expression = condition.IfFalse,
                Parent = node
            });
        }

        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            return $"{node.Children[0].FullMarkString} ? {node.Children[1].FullMarkString} : {node.Children[1].FullMarkString}";
        }

        protected override Expression Rebuild(ExpressionNode node)
        {
            var condition = node.Expression as ConditionalExpression;
            return condition.Update(node.Children[0].Expression, node.Children[1].Expression, node.Children[2].Expression);
        }

        protected override void Reduce2(ExpressionNode node)
        {
            //类似 && || 也具有短路功能
            if (node.Children[0].NodeType == ExpressionType.Constant)
            {
                var b = (node.Children[0].Expression as ConstantExpression).Value.To<bool>();
                if (b)
                {
                    var left = node.Children[1];
                    node.Expression = left.Expression;
                    node._updateRequest = true;
                    node.Children.Clear();
                    node.IsParameter = false;
                }
                else
                {
                    var right = node.Children[1];
                    node.Expression = right.Expression;
                    node._updateRequest = true;
                    node.Children.Clear();
                    node.IsParameter = false;
                }
            }
        }
    }
    /// <summary>
    /// 常量
    /// </summary>
    internal class ConstantVisit : BaseVisit
    {
        protected override void Prepare(ExpressionNode node)
        {
            var contant = node.Expression as ConstantExpression;
            if (contant.Type.IsClass && contant.Type.Name.Contains("<>c__DisplayClass") && node.Parent.Expression.NodeType == ExpressionType.MemberAccess)
            {
                //局部变量
                node.IsLocalVariable = true;
            }
        }

        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            var contant = node.Expression as ConstantExpression;
            if (node.IsLocalVariable)
            {
                return contant.Type.GetClassFullName();
            }
            else
            {
                if (contant.Type == typeof(string)) return "\"" + (contant.Value?.ToString() ?? "null") + "\"";
                return contant.Value?.ToString() ?? "null";
            }
        }
    }
    /// <summary>
    /// 示例: (int)floatx
    /// </summary>
    internal class ConvertVisit : UnaryVisit
    {
        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            var unary = node.Expression as UnaryExpression;
            return $"({unary.Type.GetClassFullName()}){node.Children[0].FullMarkString}";
        }
    }
    /// <summary>
    /// 示例: default(int)
    /// </summary>
    internal class DefaultVisit : BaseVisit
    {
        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            var d = node.Expression as DefaultExpression;
            return $"default({d.Type.GetClassFullName()})";
        }
    }
    /// <summary>
    /// 示例: dic["key"] 或 arr[i]
    /// </summary>
    internal class IndexVisit : BaseVisit
    {
        protected override void Prepare(ExpressionNode node)
        {
            var indexExpression = node.Expression as IndexExpression;
            node.Children.Add(new ExpressionNode
            {
                Expression = indexExpression.Object,
                Parent = node,
                Children = new List<ExpressionNode>(),
            });
            indexExpression.Arguments.ForEach(x => node.Children.Add(new ExpressionNode
            {
                Parent = node,
                Children = new List<ExpressionNode>(),
                Expression = x
            }));
        }

        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            var indexExpression = node.Expression as IndexExpression;
            return $"{node.Children[0].FullMarkString}[{node.Children.Skip(1).Select(i => i.FullMarkString).ToStringSeparated(",")}]";
        }

        protected override Expression Rebuild(ExpressionNode node)
        {
            var indexExpression = node.Expression as IndexExpression;
            return indexExpression.Update(node.Children[0].Expression, node.Children.Skip(1).Select(i => i.Expression));
        }
    }
    /// <summary>
    /// 示例: Func&lt;int,int> func = i=>i+1; func(1);
    /// </summary>
    internal class InvokeVisit : BaseVisit
    {
        protected override void Prepare(ExpressionNode node)
        {
            var invokeExpression = node.Expression as InvocationExpression;
            node.Children.Add(new ExpressionNode
            {
                Expression = invokeExpression.Expression,
                Parent = node,
                Children = new List<ExpressionNode>(),
            });
            invokeExpression.Arguments.ForEach(x => node.Children.Add(new ExpressionNode
            {
                Parent = node,
                Children = new List<ExpressionNode>(),
                Expression = x
            }));
        }

        protected override Expression Rebuild(ExpressionNode node)
        {
            var invokeExpression = node.Expression as InvocationExpression;
            return invokeExpression.Update(node.Children[0].Expression, node.Children.Skip(1).Select(i => i.Expression));
        }

        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            return $"{node.Children[0].FullMarkString}({node.Children.Skip(1).Select(i => i.FullMarkString).ToStringSeparated(",")})";
        }
    }
    internal class LambdaVisit : BaseVisit
    {
        protected override void Prepare(ExpressionNode node)
        {
            var lambdaExpression = node.Expression as LambdaExpression;
            node.Children.Add(new ExpressionNode
            {
                Parent = node,
                Children = new List<ExpressionNode>(),
                Expression = lambdaExpression.Body
            });
        }

        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            var lambdaExpression = node.Expression as LambdaExpression;
            return $"({lambdaExpression.Parameters.Select(i => $"{i.Type.GetClassFullName()} {i.Name}").ToStringSeparated(",")})=>{node.Children[0].FullMarkString}";
        }

        protected override Expression Rebuild(ExpressionNode node)
        {
            var lambda = node.Expression as LambdaExpression;
            return Expression.Lambda(lambda.Type, node.Children[0].Expression, lambda.Name, lambda.TailCall, lambda.Parameters);
        }
    }
    /// <summary>
    /// 示例: new List&lt;int>(){1,2,3}
    /// </summary>
    internal class ListInitVisit : BaseVisit
    {
        protected override void Prepare(ExpressionNode node)
        {
            var listInitExpression = node.Expression as ListInitExpression;
            //直接将 New 的参数扁平化到 MemberInit 里
            var args = listInitExpression.NewExpression.Arguments;
            args.ForEach(i => node.Children.Add(new ExpressionNode
            {
                Expression = i,
                Parent = node,
                Children = new List<ExpressionNode>(),
            }));
            listInitExpression.Initializers.ForEach(i => node.Children.Add(new ExpressionNode
            {
                Parent = node,
                Children = new List<ExpressionNode>(),
                Expression = i.Arguments[0]
            }));
        }

        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            var listInitExpression = node.Expression as ListInitExpression;
            var newExpression = listInitExpression.NewExpression;
            var memberSetIndex = newExpression.Arguments.Count;
            var bindings = listInitExpression.Initializers;
            var str = $"new {newExpression.Type.GetClassFullName()}({node.Children.Take(memberSetIndex).Select(i => i.FullMarkString).ToStringSeparated(",")})";

            if (bindings.Count > 0)
            {
                str += "\r\n{\r\n";
            }
            for (int i = 0; i < bindings.Count; i++)
            {
                str += $"\t{node.Children[i + memberSetIndex].FullMarkString},\r\n";
            }
            if (bindings.Count > 0)
            {
                str += "}";
            }
            return str;
        }

        protected override Expression Rebuild(ExpressionNode node)
        {
            var listInitExpression = node.Expression as ListInitExpression;
            var newExpression = listInitExpression.NewExpression;
            var inits = new List<ElementInit>();
            var memberSetIndex = newExpression.Arguments.Count;
            //先更新New
            newExpression = newExpression.Update(node.Children.Take(memberSetIndex).Select(i => i.Expression));
            //再更新ListInit
            for (int i = 1; i < node.Children.Count; i++)
            {
                inits.Add(listInitExpression.Initializers[i - 1].Update(new[] { node.Children[i].Expression }));
            }
            return listInitExpression.Update(newExpression, inits);
        }
    }
    /// <summary>
    /// 示例: obj.Name
    /// </summary>
    internal class MemberAccessVisit : BaseVisit
    {
        protected override void Prepare(ExpressionNode node)
        {
            var member = node.Expression as MemberExpression;
            node.Children.Add(new ExpressionNode
            {
                Children = new List<ExpressionNode>(),
                Expression = member.Expression,
                Parent = node
            });
        }

        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            var member = node.Expression as MemberExpression;
            return $"{node.Children[0].FullMarkString}.{member.Member.Name}";
        }

        protected override Expression Rebuild(ExpressionNode node)
        {
            var member = node.Expression as MemberExpression;
            return member.Update(node.Children[0].Expression);
        }
    }
    /// <summary>
    /// 示例: new Point { X = 1, Y = 2 }
    /// </summary>
    internal class MemberInitVisit : BaseVisit
    {
        protected override void Prepare(ExpressionNode node)
        {
            var memberInitExpression = node.Expression as MemberInitExpression;
            //直接将 New 的参数扁平化到 MemberInit 里
            var args = memberInitExpression.NewExpression.Arguments;
            args.ForEach(i => node.Children.Add(new ExpressionNode
            {
                Expression = i,
                Parent = node,
                Children = new List<ExpressionNode>(),
            }));

            memberInitExpression.Bindings.ForEach(i => node.Children.Add(new ExpressionNode
            {
                Expression = (i as MemberAssignment).Expression,
                Parent = node,
                Children = new List<ExpressionNode>(),
            }));
        }

        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            var memberInitExpression = node.Expression as MemberInitExpression;
            var newExpression = memberInitExpression.NewExpression;
            var memberSetIndex = newExpression.Arguments.Count;
            var bindings = memberInitExpression.Bindings;
            var str = $"new {newExpression.Type.GetClassFullName()}({node.Children.Take(memberSetIndex).Select(i => i.FullMarkString).ToStringSeparated(",")})";

            if (bindings.Count > 0)
            {
                str += "\r\n{\r\n";
            }
            for (int i = 0; i < bindings.Count; i++)
            {
                str += $"\t{bindings[i].Member.Name} = {node.Children[i + memberSetIndex].FullMarkString},\r\n";
            }
            if (bindings.Count > 0)
            {
                str += "}";
            }
            return str;
        }

        protected override Expression Rebuild(ExpressionNode node)
        {
            var memberInitExpression = node.Expression as MemberInitExpression;
            var newExpression = memberInitExpression.NewExpression;
            var inits = new List<MemberAssignment>();
            var memberSetIndex = newExpression.Arguments.Count;

            //先更新New
            newExpression = newExpression.Update(node.Children.Take(memberSetIndex).Select(i => i.Expression));

            //再更新MemberInit
            for (int i = memberSetIndex; i < node.Children.Count; i++)
            {
                inits.Add((memberInitExpression.Bindings[i - memberSetIndex] as MemberAssignment).Update(node.Children[i].Expression));
            }
            return memberInitExpression.Update(newExpression, inits);
        }
    }
    /// <summary>
    /// 示例: new SampleType[dim1, dim2]
    /// </summary>
    internal class NewArrayBoundsVisit : BaseVisit
    {
        protected override void Prepare(ExpressionNode node)
        {
            var newArrayExpression = node.Expression as NewArrayExpression;
            newArrayExpression.Expressions.ForEach(i => node.Children.Add(new ExpressionNode
            {
                Parent = node,
                Expression = i,
                Children = new List<ExpressionNode>()
            }));
        }

        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            var newArrayExpression = node.Expression as NewArrayExpression;
            return $"new {newArrayExpression.Type.GetClassFullName()}[{node.Children.Select(i => i.FullMarkString).ToStringSeparated(",")}]";
        }

        protected override Expression Rebuild(ExpressionNode node)
        {
            var newArrayExpression = node.Expression as NewArrayExpression;
            return newArrayExpression.Update(node.Children.Select(i => i.Expression));
        }
    }
    /// <summary>
    /// 示例: new int[] { 1, 2, 3 }
    /// </summary>
    internal class NewArrayInitVisit : BaseVisit
    {
        protected override void Prepare(ExpressionNode node)
        {
            var newArrayExpression = node.Expression as NewArrayExpression;

            newArrayExpression.Expressions.ForEach(x => node.Children.Add(new ExpressionNode
            {
                Parent = node,
                Children = new List<ExpressionNode>(),
                Expression = x,
            }));
        }

        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            var newArrayExpression = node.Expression as NewArrayExpression;
            return $"new {newArrayExpression.Type.GetClassFullName()}{{{node.Children.Select(i => i.FullMarkString).ToStringSeparated(",")}}}";
        }

        protected override Expression Rebuild(ExpressionNode node)
        {
            var newArrayExpression = node.Expression as NewArrayExpression;
            return newArrayExpression.Update(node.Children.Select(i => i.Expression));
        }
    }
    /// <summary>
    /// 示例: new Person()
    /// </summary>
    internal class NewVisit : BaseVisit
    {
        protected override void Prepare(ExpressionNode node)
        {
            var newExpression = node.Expression as NewExpression;
            newExpression.Arguments.ForEach(x => node.Children.Add(new ExpressionNode
            {
                Children = new List<ExpressionNode>(),
                Expression = x,
                Parent = node
            }));
        }

        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            var newExpression = node.Expression as NewExpression;
            return $"new {newExpression.Type.GetClassFullName()}({newExpression.Arguments.Select(i => i.Type.GetClassFullName()).ToStringSeparated(",")})";
        }

        protected override Expression Rebuild(ExpressionNode node)
        {
            var newExpression = node.Expression as NewExpression;
            return newExpression.Update(node.Children.Select(i => i.Expression));
        }
    }
    /// <summary>
    /// 参数
    /// </summary>
    internal class ParameterVisit : BaseVisit
    {
        protected override void Prepare(ExpressionNode node)
        {
            var parameter = node.Expression as ParameterExpression;
            if (node.Parameters.Contains(node.Expression))
                node.IsParameter = true;
        }

        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            var parameter = node.Expression as ParameterExpression;
            return $"{parameter.Name}";
        }
    }
    /// <summary>
    /// 示例: a as b
    /// </summary>
    internal class TypeAsVisit : UnaryVisit
    {
        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            var asExpression = node.Expression as UnaryExpression;
            return $"{node.Children[0].FullMarkString} as {asExpression.Type.GetClassFullName()}";
        }
    }
    /// <summary>
    /// 示例: obj is Person
    /// </summary>
    internal class TypeIsVisit : BaseVisit
    {
        protected override void Prepare(ExpressionNode node)
        {
            var typeBinary = node.Expression as TypeBinaryExpression;
            node.Children.Add(new ExpressionNode
            {
                Children = new List<ExpressionNode>(),
                Expression = typeBinary.Expression,
                Parent = node
            });
        }

        protected override Expression Rebuild(ExpressionNode node)
        {
            var typeBinary = node.Expression as TypeBinaryExpression;
            return typeBinary.Update(node.Children[0].Expression);
        }

        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            var typeBinary = node.Expression as TypeBinaryExpression;
            return $"{node.Children[0].FullMarkString} is {typeBinary.TypeOperand.GetClassFullName()}";
        }
    }
    /// <summary>
    /// 拆箱
    /// </summary>
    internal class UnboxVisit : UnaryVisit
    {
        protected override string GenerateFullMarkString(ExpressionNode node)
        {
            return $"unbox({node.Children[0].FullMarkString})";
        }
    }
    #endregion
}
